//! 清单管理器 (ManifestManager)
//!
//! 对应 `ai-server` 的 `services/manifest_manager.py`。

use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use crate::core::beans::bean::{Bean, BeanManager, IDestructible};
use crate::core::beans::constants::expansion_seed_names;
use crate::core::manifest::{ActivationEvent, ActivationEventDefinition, ExpansionManifest};

/// 清单管理器的结构体
pub struct ManifestManager {
    manifest_map: Mutex<HashMap<String, ExpansionManifest>>,
    group_by_activation_event: Mutex<HashMap<String, Vec<(ExpansionManifest, ActivationEvent)>>>,
}

impl IDestructible for ManifestManager {
    fn destructor(&self) {
        self.manifest_map.lock().unwrap().clear();
        self.group_by_activation_event.lock().unwrap().clear();
        println!("ManifestManager destroyed.");
    }
}

impl Bean for ManifestManager {
    fn new(bean_manager: &Arc<BeanManager>) -> Arc<Self> {
        let manifests_seed = bean_manager
            .get_bean::<Vec<ExpansionManifest>>(expansion_seed_names::MANIFESTS)
            .expect("Manifests seed not found");

        let activation_events_seed = bean_manager
            .get_bean::<Vec<ActivationEventDefinition>>(expansion_seed_names::ACTIVATION_EVENT_DEFINITIONS)
            .expect("ActivationEventDefinitions seed not found");

        let mut manifest_map = HashMap::new();
        let mut group_by_activation_event: HashMap<String, Vec<(ExpansionManifest, ActivationEvent)>> = HashMap::new();

        for event_def in activation_events_seed.iter() {
            group_by_activation_event.insert(event_def.name.clone(), Vec::new());
        }

        for manifest in manifests_seed.iter() {
            // TODO: 在这里执行断言和验证 `assert_manifest_is_valid`
            manifest_map.insert(manifest.name.clone(), manifest.clone());

            for event in &manifest.activation_events {
                let event_name = event.get_name();
                if let Some(group) = group_by_activation_event.get_mut(event_name) {
                    group.push((manifest.clone(), event.clone()));
                }
            }
        }

        Arc::new(Self {
            manifest_map: Mutex::new(manifest_map),
            group_by_activation_event: Mutex::new(group_by_activation_event),
        })
    }
}

impl ManifestManager {
    pub fn get_manifest(&self, name: &str) -> Option<ExpansionManifest> {
        self.manifest_map.lock().unwrap().get(name).cloned()
    }

    pub fn get_should_activates(&self, activation_event_name: &str) -> Vec<(ExpansionManifest, ActivationEvent)> {
        self.group_by_activation_event
            .lock()
            .unwrap()
            .get(activation_event_name)
            .cloned()
            .unwrap_or_default()
    }

    pub fn get_should_deactivates(&self, activation_event_name: &str) -> Vec<ExpansionManifest> {
        self.group_by_activation_event
            .lock()
            .unwrap()
            .get(activation_event_name)
            .map(|activates| activates.iter().map(|(m, _)| m.clone()).collect())
            .unwrap_or_default()
    }

    pub fn get_all_manifests(&self) -> Vec<ExpansionManifest> {
        self.manifest_map.lock().unwrap().values().cloned().collect()
    }

    pub async fn dynamic_add_manifest(&self, manifests: Vec<ExpansionManifest>) {
        // TODO: Implement assertion checks for the new manifests
        let mut manifest_map = self.manifest_map.lock().unwrap();
        let mut group_by_activation_event = self.group_by_activation_event.lock().unwrap();

        for manifest in manifests {
            manifest_map.insert(manifest.name.clone(), manifest.clone());
            for event in &manifest.activation_events {
                let event_name = event.get_name();
                if let Some(group) = group_by_activation_event.get_mut(event_name) {
                    group.push((manifest.clone(), event.clone()));
                }
            }
        }
    }
}
